<?php

/**
 * 装饰器模式:基于接口实现
 */
interface AnyThing {
    function exe();
}

/**
 * 定义三个没有任何耦合关系的类
 */
class Moon implements AnyThing {
    private $param;

    public function __construct($param) {
        $this->param = $param;
    }

    public function exe() {
        echo "明月装饰了";
        $this->param->exe();
    }
}

class Dream implements AnyThing {
    private $param;

    public function __construct($param) {
        $this->param = $param;
    }

    public function exe() {
        echo "梦装饰了";
        $this->param->exe();
    }
}

class You implements AnyThing {
    private $param;

    public function __construct($param) {
        $this->param = $param;
    }

    public function exe() {
        echo "你";
    }
}


//创建对象的时候，可以通过构造函数的不同次序，使这几个类互相调用，从而呈现不同的装饰结果
$data1 = new Moon(new Dream(new You(null)));
$data1->exe(); //明月装饰了梦装饰了你
echo PHP_EOL;

$data2 = new Dream(new Moon(new You(null)));
$data2->exe(); //梦装饰了明月装饰了你
echo PHP_EOL;